<template>
  <div class="chat-container dark h-full flex dark:bg-#24272e transition-all">
    <div class="transition wp-100 flex h-full">
      <!-- sider -->
      <Sider />

      <!-- 对话框 -->
      <div class="chat-box h-full bg-#292a2d flex-1 m-w-0">
        <div class="h-full flex flex-col text-#fff justify-center">
          <div
            class="h-50px leading-50px text-20px text-center px-20px"
            v-if="dataSources.length"
          >
            {{ currentChatHistory?.title }}
          </div>
          <main
            class="overflow-hidden"
            :class="{ 'flex-1': dataSources.length }"
          >
            <el-scrollbar ref="scrollRef">
              <div id="scroll-box" class="w-full max-w-screen-md m-auto">
                <div v-if="!dataSources.length" class="text-center p-20px">
                  <div class="text-26px font-bold">
                    我是 DeepSeek，很高兴见到你
                  </div>
                  <div class="text-14px mt-10px">
                    我可以帮你写代码、读文件、写作各种创意内容，请把你的任务交给我吧~
                  </div>
                </div>
                <div v-else>
                  <Message
                    v-for="(item, index) in dataSources"
                    :key="index"
                    :date-time="item.dateTime"
                    :text="item.text"
                    :reasoning="item.reasoning"
                    :inversion="item.inversion"
                    :error="item.error"
                    :loading="item.loading"
                  />
                </div>
              </div>
            </el-scrollbar>
          </main>

          <footer>
            <div class="py-20px max-w-screen-md m-auto">
              <div class="p-15px bg-#404045 rounded-24px">
                <div class="input-box">
                  <el-input
                    v-model="prompt"
                    style="width: 100%"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    type="textarea"
                    resize="none"
                    placeholder="发送消息"
                    @keypress="handleEnter"
                  />
                </div>
                <div class="flex items-center justify-between">
                  <div></div>
                  <div class="flex items-center">
                    <el-button
                      v-if="loading"
                      type="primary"
                      :icon="CloseBold"
                      circle
                      @click="handleStop"
                    />
                    <el-button
                      v-else
                      type="primary"
                      :icon="Position"
                      :disabled="!prompt"
                      circle
                      @click="handleSubmit"
                    />
                  </div>
                </div>
              </div>
            </div>
          </footer>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import Sider from './layout/sider/index.vue'
import Message from './components/Message/index.vue'
import { Position, CloseBold } from '@element-plus/icons-vue'
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { chatCompletions } from '@/api/chat'
import { useChat } from './hooks/useChat'
import { useScroll } from './hooks/useScroll'
import { useStore } from 'vuex'
import { useRoute, useRouter } from 'vue-router'
import { useReadStream } from './hooks/useReadStream'
import { getItem, setItem } from '@/utils/storage'

let controller = new AbortController()
const store = useStore()
const route = useRoute()
const router = useRouter()
const uuid = route.params.uuid || ''
const prompt = ref('')
const loading = ref(false)

const { addChat, updateChat } = useChat()
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll()
const { handleStreamResponse } = useReadStream()

// 对话记录
console.log('==uuid', uuid, '/', +uuid)
const dataSources = computed(() => store.getters['chat/getChatByUuid'](+uuid))
console.log('==dataSources:', dataSources)

const currentChatHistory = computed(() => store.getters['chat/getChatHistoryByCurrentActive'])
console.log('==currentChatHistory:', currentChatHistory)

const active = computed(() => store.state.chat.active)
console.log('==store.state.active:', active.value)

const usingContext = computed(() => store.state.usingContext)
console.log('==usingContext:', usingContext)

function handleEnter (event) {
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    handleSubmit()
  }
}

async function handleSubmit () {
  console.log('==handleSubmit', +uuid)
  if (!+uuid || +uuid === 0) {
    try {
      await store.dispatch('chat/addHistory', {
        history: {
          title: '新建会话',
          uuid: Date.now(),
          isEdit: false,
          visible: false
        },
        chatData: [],
        router
      })

      setItem('chatSubmitPrompt', prompt.value)
      return
    } catch (error) {
      console.error('创建会话失败:', error)
    }
  }

  onConversation()
}

async function onConversation () {
  const message = prompt.value
  if (loading.value) return
  if (!message || message.trim() === '') return

  controller = new AbortController()
  const conversationList = dataSources.value
    .filter(item => item.text)
    .map(item => ({
      role: item.inversion ? 'user' : 'assistant',
      content: item.text
    }))

  addChat(+uuid, {
    dateTime: new Date().toLocaleString(),
    text: message,
    inversion: true,
    error: false
  })
  scrollToBottom()
  loading.value = true
  prompt.value = ''

  addChat(+uuid, {
    dateTime: new Date().toLocaleString(),
    text: '',
    reasoning: '思考中...',
    loading: true,
    inversion: false,
    error: false
  })
  scrollToBottom()

  try {
    const paramMsg = []
    if (usingContext.value) {
      paramMsg.push(...conversationList)
    }
    paramMsg.push({ role: 'user', content: message })
    const response = await chatCompletions(controller.signal, paramMsg)
    await handleStreamResponse(response, jsonData => {
      if (jsonData.choices.length === 0) {
        return
      }
      console.log('==handleStreamResponse-jsonData', jsonData)
      const contentText = jsonData.choices[0]?.delta?.content
      console.log('==handleStreamResponse-contentText', contentText)
      if (contentText) {
        updateChat(+uuid, dataSources.value.length - 1, {
          text: contentText || '',
          inversion: false,
          error: false,
          loading: true
        })
        scrollToBottomIfAtBottom()
      }
      const reasoning = jsonData.choices[0].delta.reasoning_content
      console.log('==handleStreamResponse-reasoning', reasoning)
      if (reasoning) {
        updateChat(+uuid, dataSources.value.length - 1, {
          reasoning: reasoning || '',
          reasoningTime: new Date().toLocaleString(),
          inversion: false,
          error: false,
          loading: true
        })
        scrollToBottomIfAtBottom()
      }
    })
    updateChat(+uuid, dataSources.value.length - 1, {
      inversion: false,
      error: false,
      loading: false
    })
    loading.value = false
    console.log('onConversation', 'Stream ended')
  } catch (error) {
    console.log('onConversation', error)
    loading.value = false
    if (error instanceof DOMException && error.name === 'AbortError') {
      updateChat(+uuid, dataSources.value.length - 1, {
        text: '\n\n用户手动中断。',
        inversion: false,
        error: false,
        loading: false
      })
    } else {
      updateChat(+uuid, dataSources.value.length - 1, {
        text: '\n\n服务器异常，请稍后再试。',
        inversion: false,
        error: true,
        loading: false
      })
    }
  }
}

function handleStop () {
  if (loading.value) {
    controller.abort()
    loading.value = false
  }
}

onMounted(() => {
  console.log('==onMounted', prompt.value)
  if (!route.params.uuid) {
    store.state.active = 1002
  }
  const promptValue = getItem('chatSubmitPrompt')
  console.log('==promptValue', promptValue)
  if (promptValue) {
    prompt.value = promptValue
    setItem('chatSubmitPrompt', '')
    onConversation()
  }
  scrollToBottom()
})

onUnmounted(() => {
  console.log('onUnmounted')
  if (loading.value) controller.abort()
})
</script>

<style scoped lang="scss">
@import url('./chat.scss');
.chat-container {
  min-height: calc(100vh - 50px - 43px - 30px);
  border-radius: 2px;
  .chat-box {
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
  }
}
.input-box {
  :deep(.el-textarea) {
    .el-textarea__inner {
      background-color: transparent;
      color: #fff;
      box-shadow: none;
      padding: 0;
      font-size: 16px;
    }
  }
}
</style>
